import pandas as pd
from matplotlib import pyplot as plt
from sklearn.cluster import KMeans

from Iris.Manual_KMeans import ManualKMeans
from Iris.Manual_KNNClassifier import ManualKNNClassifier

# 定义列名 花瓣、花萼
col_names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Species']

# 加载数据集
iris = pd.read_csv('../data/Iris.csv', names=col_names, header=0)  # header=0 表示文件有表头

# 查看前五行数据
print(iris.head())

# 删除 'Species' 列以便进行聚类分析（对特征和分类进行分离）
iris_clustering = iris.drop(columns=['Species'])

# 选择两个随机特征进行聚类，这里选择的是花萼长度和花瓣长度
X = iris_clustering.iloc[:, [0, 2]].values

# 使用肘部法（Elbow Method）确定最佳聚类数
wcss = []  # 保存不同聚类数对应的 WCSS 值（聚类内部平方和）
for i in range(1, 11):
    kmeans = ManualKMeans(n_clusters=i, random_state=42)
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)  # inertia_ 表示样本点到最近质心的距离平方和

# 绘制肘部法图形
plt.plot(range(1, 11), wcss, marker='o', linestyle='--')
plt.title('The Elbow Point Graph on Iris Dataset')
plt.xlabel('Number of Clusters')
plt.ylabel('WCSS')
plt.grid(alpha=0.6)
plt.show()

# 根据肘部法选择聚类数为 3，并对数据进行聚类
kmeans = ManualKMeans(n_clusters=3, random_state=42)
# 对数据进行聚类，并返回每个点的标签
y = kmeans.fit_predict(X)

# 输出聚类标签、惯性值、迭代次数和聚类中心
print("Cluster Labels:", y)
print("Inertia (WCSS):", kmeans.inertia_)
print("Number of Iterations:", kmeans.n_iter_)
print("Cluster Centers:\n", kmeans.cluster_centers_)

# 可视化聚类结果
plt.scatter(X[y == 0, 0], X[y == 0, 1], s=50, c='red', label='Cluster 1')
plt.scatter(X[y == 1, 0], X[y == 1, 1], s=50, c='blue', label='Cluster 2')
plt.scatter(X[y == 2, 0], X[y == 2, 1], s=50, c='green', label='Cluster 3')

# 绘制聚类中心
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
            s=200, c='cyan', marker='X', edgecolors='black', label='Centroids')

# 添加图形标题和标签
plt.title('Iris Flower Clusters')
plt.xlabel('Sepal Length (cm)')
plt.ylabel('Petal Length (cm)')
plt.legend()
plt.grid(alpha=0.7)
plt.show()